home *** CD-ROM | disk | FTP | other *** search
- Path: news.iag.net!news
- From: jatmon@iag.net (John R Buchan)
- Newsgroups: alt.msdos.programmer,comp.lang.c
- Subject: Re: Two C problems
- Date: 8 Jan 1996 17:16:19 GMT
- Organization: Internet Access Group, Orlando, Florida
- Distribution: world
- Message-ID: <4crjh3$d71@news.iag.net>
- References: <4cojnn$rgd@lugb.latrobe.edu.au>
- NNTP-Posting-Host: pm3-orl29.iag.net
- X-Newsreader: WinVN 0.99.7
-
- In article <4cojnn$rgd@lugb.latrobe.edu.au>, csigjb@luxor.latrobe.edu.au
- says...
- >
- >I have two C problems.
-
- The following is a reformatted (sorry, I prefer my format) version of the
- full version of the code that was originally posted (sorry about the rather
- large post folks). I have made a few modifications (I think I remembered to
- add comments by each. Please excuse those that you have already corrected
- in your second post) and it now seems to be functional (though I can't be
- certain that it functions the way you expected). BTW, You might want to
- consider breaking your main into smaller functions.
-
- As a few people have probably mentioned, it is considered rather poor taste
- to post non-ansi code in c.l.c and even worse to post incomplete uncompilable
- code. Always try to post a minimum compilable example (as little non-ansi
- code as possible) that illustrates your problem. It is sometimes easier to
- write a new small program for this rather than trying to edit the original
- (just be sure that it probuces the same problem) A consistant format and
- well placed comments are also helpful.
-
- #include <stdio.h>
- #include <stdlib.h> /* needed for ansi exit() and EXIT_FAILURE */
- #include <conio.h>
- #include <string.h>
- #include <alloc.h>
- #include <process.h>
-
- /* it is fairly common practice to use all caps in the names of globals. */
- #define maxstring 127 /* this should be a constant expression not a const */
- const lineend='\n';
- const escape=27;
- const null='\0'; /* Using nul for this name will cause less confusion. */
- const space=' ';
- const up='H';
- const down='P';
- const pageup='I';
- const pagedown='Q';
- const left='K';
- const right='M';
- const home='G';
- const end_='O';
-
-
- typedef char string[maxstring]; /* needs a constant expression, not a const */
- typedef struct nodetypetag
- {
- string line;
- int linenum;
- struct nodetypetag *next,*previous;
- } nodetype;
-
- typedef nodetype *nodetypeptr;
-
- string line,line_,line1,bottomline;
-
- char empty(nodetypeptr posptr)
- {
- return(posptr==NULL);
- }
-
- void initialize(nodetypeptr *listptr)
- {
- *listptr=NULL;
- }
-
- void add(nodetypeptr *listptr,char *fileline,int Linenum)
- {
- nodetypeptr newptr,tempptr;
-
- newptr=(nodetypeptr)malloc(sizeof(nodetype));
- /* need to verify allocation success */
-
- strcpy(newptr->line,fileline);
- newptr->linenum=Linenum;
- newptr->next=NULL; /* no need to write this twice */
- if (*listptr==NULL)
- {
- (*listptr)=newptr;
- /* (*listptr)->next=NULL; not needed */
- (*listptr)->previous=NULL;
- }
- else
- {
- tempptr=*listptr;
- while (tempptr->next!=NULL)
- {
- tempptr=tempptr->next;
- }
- tempptr->next=newptr;
- /* newptr->next=NULL; not needed */
- newptr->previous=tempptr;
- }
- }
-
- /* void remove(nodetypeptr *listptr) name is in conflict with the ansi */
- /* function remove, which is prototyped in stdio.h */
- void RemoveNode(nodetypeptr *listptr)
- {
- nodetypeptr tempptr;
-
- /* NULL tests missing */
- if( listptr != NULL && *listptr != NULL) /* at least 1 node exists */
- {
- tempptr=*listptr;
- *listptr=(*listptr)->next;
- (*listptr)->previous=NULL;
- free(tempptr);
- }
- }
-
- /* This would probably work better as: *
- * *
- * nodetypeptr setpos( int linenum) *
- * *
- * This would reduce the number of indirects and allow you to return *
- * NULL, if an invalid number manages to be passed in. */
- void setpos(nodetypeptr *posptr,int linenum)
- {
- while ((*posptr)->linenum!=linenum)
- {
- if ((*posptr)->linenum>linenum)
- {
- *posptr=(*posptr)->previous;
- }
- else
- if ((*posptr)->linenum<linenum)
- {
- *posptr=(*posptr)->next;
- }
- }
- }
-
- void writescreenfull(char width,char height,nodetypeptr posptr,char stringpos)
- {
- char y;
- char *line__; /* this definition was apparently left out */
-
- window(1,1,width,height);
- clrscr();
- window(1,1,width,height+1);
- y=1;
- while ((y<=height) && (!empty(posptr->next)))
- {
- gotoxy(1,y);
- strcpy(line_,posptr->line);
- line__=&(line_[stringpos]); /* line__ = line_ + stringpos; */
- strncpy(line,line__,width-1);
- /* strcat(line,null); someone else explained this already */
- line[maxstring - 1] = '\0'; /* this provides your safety */
- cputs(line);
- posptr=posptr->next;
- y++;
- }
- }
-
- /* Since fgets will always append a '\0', there is no need for the *
- * maxstrings parameter. Just test for '\0' and '\n' or use the ansi *
- * strrchr function. */
- void removelineends(char *strings,unsigned int maxstrings)
- {
- unsigned int i;
-
- i=0;
- while ((i<maxstrings) && (strings[i]!=lineend))
- {
- i++;
- }
- strings[i]=null;
- }
-
- int main(int argc,char *argv[]) /* main must return int */
- {
- FILE *file;
- char x,ch,width,height,back,fore,stringpos;
- int numlines,linenum;
- struct text_info info; /* forgot the struct */
- nodetypeptr listptr,posptr;
-
-
- if (argc<2)
- {
- cputs("\nShow what . . .\n");
- exit(EXIT_FAILURE); /* exit with failure value, when code fails */
- }
- else
- {
- file=fopen(argv[1],"rt");
- if (file==NULL)
- {
- cprintf("\nFile %s not found . . .\n",argv[1]);
- exit(EXIT_FAILURE); /* exit with failure value, when code fails */
- }
- else
- {
- rewind(file); /* not needed, "r" opens to the beginning anyway */
- initialize(&listptr);
- linenum=0;
- while (fgets(line,maxstring,file)!=NULL)
- {
- removelineends(line,maxstring);
- add(&listptr,line,linenum);
- linenum++;
- }
- numlines=linenum--; /* ?? */
- fclose(file);
-
- posptr=listptr;
-
- /* This would make a nice 'InitScreen' function */
- gettextinfo(&info);
- fore=info.attribute&0x0f;
- back=(info.attribute&0x70)/0x10;
- height=info.screenheight;
- width=info.screenwidth;
- strcpy(bottomline," \30 \31 pgup pgdn s <string> "
- "(search for string) esc (quit)");
- for(x=strlen(bottomline)+1;x<width;x++)
- {
- strcat(bottomline," ");
- }
- /* look into sprintf */
-
- _setcursortype(_NOCURSOR);
- clrscr();
- textcolor(back);
- textbackground(fore);
- gotoxy(1,height);
- cputs(bottomline);
- textcolor(fore);
- textbackground(back);
- /* end 'InitScreen' function */
-
- height--;
- linenum=0; /* the first line in your list is 0, not 1 */
- stringpos=0; /* this should start at 0, not 1 */
- writescreenfull(width,height,posptr,stringpos);
- ch=space;
- while (ch!=escape)
- {
- while ((ch!=up) && (ch!=down) && (ch!=pageup) &&
- (ch!=pagedown) && (ch!=escape) && (ch!=left) &&
- (ch!=right) && (ch!=end_) && (ch!=home))
- {
- ch=getch();
- if (ch==null)
- {
- ch=getch();
- }
- }
-
- /* This would be much clearer using a switch statement */
- if (ch==up)
- {
- if ((linenum-1)>=0)
- {
- linenum--;
- }
- else
- {
- linenum=0;
- }
- setpos(&posptr,linenum);
- }
- else
- if (ch==down)
- {
- if ((linenum+1+height)<=numlines) /* ?? */
- {
- linenum++;
- }
- else
- {
- linenum=numlines-height+1;
- }
- setpos(&posptr,linenum);
- }
- else
- if (ch==pageup)
- {
- if ((linenum-height+1)>=1)
- {
- linenum=linenum-height+1;
- }
- else
- {
- linenum=1;
- }
- setpos(&posptr,linenum);
- }
- else
- if (ch==pagedown)
- {
- if (((linenum+height-1)<=numlines) &&
- ((numlines-(linenum+height-1))>=(height-1)))
- {
- linenum=linenum+height-1;
- }
- else
- {
- linenum=numlines-height+1;
- }
- setpos(&posptr,linenum);
- }
- else
- if (ch==left)
- {
- if (stringpos>0) /* s/b 0 */
- {
- stringpos--;
- }
- }
- else
- if (ch==right)
- {
- if (stringpos<=(maxstring-width))
- {
- stringpos++;
- }
- }
- else
- if (ch==end_)
- {
- stringpos=maxstring-width+1;
- }
- else
- if (ch==home)
- {
- stringpos=0; /* s/b 0, not 1 */
- }
- if (ch!=escape)
- {
- ch=space;
- }
- writescreenfull(width,height,posptr,stringpos);
- }
- height+=1;
- window(1,1,width,height);
- clrscr();
- _setcursortype(_NORMALCURSOR);
- while (!empty(listptr))
- {
- RemoveNode(&listptr);
- }
- }
- }
-
- return 0;
- }
-
-
-
- --
- John R Buchan -:|:- Looking for that elusive FAQ? ftp to:
- jatmon@mail.iag.net -:|:- rtfm.mit.edu /pub/usenet-by-group/....
-
-